import 'dart:async';

import 'package:flutter/material.dart';
import 'package:x3_component_core/components/state_components/base_bottom_loading_component.dart';
import 'package:x3_component_core/components/state_components/base_nomore_component.dart';
import 'package:x3_component_core/enums/loading_status_enum.dart';
import 'package:x3_component_core/components/state_components/base_empty_component.dart';
import 'package:x3_component_core/components/state_components/base_loading_component.dart';

import 'base_message_component.dart';

typedef RefreshFuture = Future<List<Map<String, dynamic>>> Function();

typedef LoadingFuture = Future<List<Map<String, dynamic>>> Function();

/// 自定义下拉刷新 上拉加载的ListView
class BaseMessageContainerComponent extends StatefulWidget {
  /// 是否需要上拉加载更多
  final bool needLoading;

  /// 上拉加载的回调事件
  final LoadingFuture onLoading;

  /// 刷新数据
  final RefreshFuture onRefresh;

  /// 子item的创建函数
  final Widget Function(BuildContext context, int index, dynamic item) builder;

  /// 分割线
  final Widget Function(BuildContext context, int index, dynamic item) separatorBuilder;

  /// 是否默认加载数据
  final bool autoLoad;

  /// 获取下拉刷新的RefreshIndicatorState 通用
  final void Function(GlobalKey<RefreshIndicatorState>) getRefreshIndicatorState;

  /// 内边距
  final EdgeInsets padding;

  /// 预加载
  final double cacheExtent;

  /// 刷新数据加载完成事件
  final Function(List<Map<String, dynamic>> items) refreshDataLoadComplete;

  /// 构造函数
  BaseMessageContainerComponent({
    Key key,
    @required this.builder,
    @required this.separatorBuilder,
    @required this.getRefreshIndicatorState,
    @required this.onRefresh,
    this.padding = EdgeInsets.zero,
    this.autoLoad = true,
    this.needLoading = false,
    this.onLoading,
    this.cacheExtent,
    this.refreshDataLoadComplete,
  })  : assert(separatorBuilder != null),
        super(key: key);

  @override
  _BaseMessageContainerComponentState createState() => _BaseMessageContainerComponentState();
}

class _BaseMessageContainerComponentState extends State<BaseMessageContainerComponent> {
  final ScrollController _controller = new ScrollController();

  final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey = new GlobalKey<RefreshIndicatorState>();

  /// 加载状态
  LoadingStatusEnum _loadingStatus = LoadingStatusEnum.LoadingComplete;

  /// 数据源
  List<Map<String, dynamic>> _items;

  @override
  void initState() {
    super.initState();
    this._onRefreshData();
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      widget.getRefreshIndicatorState(_refreshIndicatorKey);
    });
    _controller.addListener(() {
      // 当前位置信息
      var position = _controller.position;
      if (position.maxScrollExtent == position.pixels) {
        //加载更多
        if (_loadingStatus != LoadingStatusEnum.Loading) {
          _onLoadingData();
        }
      }
    });
  }

  /// 刷新数据
  Future _onRefreshData() async {
    if (widget.autoLoad == true && widget.onRefresh != null) {
      List<Map<String, dynamic>> items = await widget.onRefresh();
      if (this.mounted == true) {
        setState(() {
          this._items = items;
          this._items = this._items.reversed.toList();
          this._loadingStatus = LoadingStatusEnum.LoadingComplete;
        });
        if (widget.refreshDataLoadComplete != null) {
          widget.refreshDataLoadComplete(this._items);
        }
        // Timer(Duration(milliseconds: 500), () => _controller.jumpTo(_controller.position.maxScrollExtent));
      }
    }
  }

  /// 加载更多数据
  Future _onLoadingData() async {
    if (widget.needLoading == true && widget.onLoading != null) {
      if (this.mounted == true) {
        setState(() {
          this._loadingStatus = LoadingStatusEnum.Loading;
        });
      }
      List<Map<String, dynamic>> items = await widget.onLoading();
      if (this.mounted == true) {
        if (items.length == 0) {
          setState(() {
            this._loadingStatus = LoadingStatusEnum.NoMore;
          });
        } else {
          setState(() {
            this._items = [...this._items, ...items.reversed.toList()];
            if (widget.refreshDataLoadComplete != null) {
              widget.refreshDataLoadComplete(this._items);
            }
            this._loadingStatus = LoadingStatusEnum.LoadingComplete;
          });
        }
      }
    }
  }

  /// 构建子Item项
  Widget _buildListItem(BuildContext context, int index) {
    if (this._items.length == 0) return _buildNoDataWidget();
    if (index != this._items.length) return widget.builder(context, index, this._items[index]);
    if (index == this._items.length) return _buildBottomLoadingStateWidget();
    return Container();
  }

  /// 构建底部加载更多的动画
  Widget _buildBottomLoadingStateWidget() {
    switch (this._loadingStatus) {
      case LoadingStatusEnum.Loading:
        return BaseBottomLoadingComponent();
        break;
      case LoadingStatusEnum.LoadingComplete:
        return null;
        break;
      case LoadingStatusEnum.NoMore:
        return BaseNoMoreComponent();
        break;
    }
    return null;
  }

  Widget _buildListSeparatorItem(BuildContext context, int index) {
    return widget.separatorBuilder(context, index, this._items[index]);
  }

  /// 构建没有数据时的显示
  Widget _buildNoDataWidget() {
    if (this._items.length == 0) {
      return Padding(padding: EdgeInsets.symmetric(vertical: 20.0), child: BaseEmptyComponent());
    }
    return SizedBox();
  }

  @override
  Widget build(BuildContext context) {
    return this._items == null ? BaseLoadingComponent() : _buildRefreshIndicatorListViewWidget();
  }

  /// 创建列表
  Widget _buildRefreshIndicatorListViewWidget() {
    return RefreshIndicator(
      key: _refreshIndicatorKey,
      color: Theme.of(context).primaryColor,
      onRefresh: _onRefreshData,
      child: _buildListViewWidget(),
    );
  }

  Widget _buildListViewWidget() {
    return ListView.separated(
      reverse: true,
      cacheExtent: widget.cacheExtent,
      padding: widget.padding,
      separatorBuilder: _buildListSeparatorItem,
      itemBuilder: _buildListItem,
      itemCount: this._items.length + 1,
      controller: _controller,
      physics: const AlwaysScrollableScrollPhysics(),
      // 注意这里一定要加这个属性 不然无法下拉刷新
      shrinkWrap: true,
    );
  }

  @override
  void dispose() {
    _controller?.dispose();
    super.dispose();
  }
}
